home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
filesyst
/
thsfs.tgz
/
thsfs.tar
/
thsfs
/
fat.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-04
|
4KB
|
229 lines
/*************************************************************
* *
* ths Filesystem 04.10.94 V1.1 *
* *
* Thomas Scheuermann ths@ai-lab.fh-furtwangen.de *
* *
*************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/mm.h>
#include <linux/locks.h>
#include <linux/fs.h>
#include <linux/malloc.h>
#include "ths.h"
#include "ths_i.h"
void fatfree(struct super_block *s)
{
int i;
struct ths_sb_info *ths_sb;
ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
#ifdef DEBUG
printk("fatfree\n");
#endif
/*
* Speicher der Clusteradressen freigeben
*/
for(i=0;i<ths_sb->AnzahlCluster+2;)
{
kfree_s(ths_sb->fat[i/2048],4096);
i+=2048;
}
}
void fatmem2(struct super_block *s)
{
struct ths_sb_info *ths_sb;
struct ths_buffer tbf;
int i,k,t;
unsigned short cl1,cl2,cluster,addr;
unsigned char *data=NULL;
ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
#ifdef DEBUG
printk("fatmem2\n");
#endif
/*
* Speicher fuer alle Clusteradressen holen
*/
for(i=0;i<ths_sb->AnzahlCluster+2;)
{
ths_sb->fat[i/2048] = (short *)kmalloc(4096,GFP_KERNEL);
i+=2048;
}
#ifdef DEBUG
printk("Speicher erhalten : %d\n",i);
#endif
/*
* k : Nibble-Zaehler
* addr : Adresse des Speicherblocks
* i : Byte vom Clustersektor
* addr : Adresse im FAT-Speicher = Clusternummer
*/
t = ths_sb->BitsProCluster/4;
cl1 = 0;
cl2 = 0;
addr = 0;
k = 0;
for(i=0,addr=0;addr<(ths_sb->AnzahlCluster+2);)
{
if(!(i & 0x1ff))
{
if(ths_read_sektor(s,ths_sb->FatStart+(i>>9),&tbf))
{
printk("Fehler\n");
return;
}
data = tbf.data[0];
}
cl1 = (short)data[i&0x1ff];
k=(k+1)%t;
if(!k)
{
cluster = (cl2 | ((cl1<<8)&0x0fff));
(ths_sb->fat[addr/2048])[addr%2048] = cluster;
addr++;
}
k=(k+1)%t;
if(!k)
{
if(t==3)
{
cluster = ((cl2 & 0xf0) >> 4) | (cl1 << 4);
}
else
{
cluster = cl2 | (cl1 << 8);
}
(ths_sb->fat[addr / 2048])[addr % 2048] = cluster;
addr++;
}
cl2 = cl1;
i++;
if(!(i & 0x1ff))
ths_free_sektor(&tbf);
}
if(i & 0x1ff)
ths_free_sektor(&tbf);
}
void cvffill(struct super_block *s)
{
struct ths_sb_info *ths_sb;
struct buffer_head *fbh;
int i,j,clb;
unsigned short cl1,cluster,test;
unsigned char *data=NULL,b1=0;
unsigned long fatsektor;
ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
#ifdef DEBUG
printk("cvffill\n");
#endif
cluster = ths_sb->StartCluster;
cl1 = cluster;
ths_sb->cvf[0] = NULL;
if(ths_sb->uBitsProCluster==12)
test = 0x0fff;
else
test = 0xffff;
for(i=0;cl1!=test;)
{
clb = (cluster*(ths_sb->uBitsProCluster>>2));
fatsektor = ths_sb->uFATStart + ((clb>>1)/512);
fbh = bread(s->s_dev,fatsektor>>1,BLOCK_SIZE);
j=0;
if(fatsektor&1)
j=512;
data = &(fbh->b_data[j]);
b1 = data[(clb>>1) & 0x1ff];
if(clb & 1)
cluster = (unsigned short)(b1 & 0xf0)>>4;
else
cluster = (unsigned short)b1;
if(((clb>1) & 0x1ff)==511)
{
brelse(fbh);
fbh = bread(s->s_dev,(fatsektor+1)>>1,BLOCK_SIZE);
j=0;
if((fatsektor+1)&1)
j=512;
data = &(fbh->b_data[j]);
}
b1 = data[((clb>>1)+1) & 0x1ff];
if(clb & 1)
cluster |= (unsigned short)b1 << 4;
else
cluster |= (unsigned short)b1 << 8;
if(ths_sb->uBitsProCluster == 12)
cluster &=0xfff;
brelse(fbh);
if(cluster != cl1+1)
{
if(!(i%2048))
{
ths_sb->cvf[i/2048] = (short *)kmalloc(4096,GFP_KERNEL);
ths_sb->cvf[i/2048+1] = NULL;
}
(ths_sb->cvf[i/2048])[i%2048] = cl1;
i++;
(ths_sb->cvf[i/2048])[i%2048] = cluster;
i++;
#ifdef DEBUG
printk("Nach %d folgt %d\n",cl1,cluster);
#endif
}
cl1 = cluster;
}
#ifdef DEBUG
printk("Luecken : %d\n",i/2);
#endif
}
void cvffree(struct super_block *s)
{
int i;
struct ths_sb_info *ths_sb;
ths_sb = (struct ths_sb_info *)s->u.generic_sbp;
#ifdef DEBUG
printk("cvffree\n");
#endif
/*
* Speicher der Clusteradressen freigeben
*/
for(i=0;ths_sb->cvf[i/2048]!=NULL;)
{
kfree_s(ths_sb->cvf[i/2048],4096);
i+=2048;
}
}